<template>
  <div class="container">
    <div class="tabs-lb">
      <span>服务流程编辑</span>
      <button class="btn_operation_add" @click="saveMx">保存</button>
      <button class="btn_operation_add" @click="addNode">新增节点</button>
    </div>
    <!-- 流程图 -->
    <div class="lct" ref="lctRef"></div>

    <!-- 编辑节点弹窗 -->
    <edit-node-dialog ref="editNodeDialog" @updateLct="updateLct" />
  </div>
</template>
<script>
import bpfwglService from "@/api/bpfwgl";
import { Graph } from "@antv/x6";
import { MessageBox } from "element-ui";
import EditNodeDialog from "./dialogs/edit-node-dialog.vue";
import { uuid } from "@/utils/uuid";

export default {
  components: { EditNodeDialog },
  name: "fwbp",
  data() {
    return {
      // 流程图画布
      graph: null,
      // 服务定义
      fwdy: "",
      // 编辑类型
      editType: "",
      // 选中的节点
      activeNode: null
    };
  },
  mounted() {
    // 初始化流程图
    this.initLct();
  },
  activated() {
    // 获取数据
    this.getData();
  },
  methods: {
    /*
     * 获取数据
     */
    getData() {
      const params = {
        fwdybh: this.$route.query.cs
      };
      bpfwglService
        .getBpfw(params)
        .then(res => {
          this.fwdy = res.fwdy;
          this.$nextTick(() => {
            this.graph.fromJSON(JSON.parse(this.fwdy) || {});
          });
        })
        .catch(err => {
          !err.isError &&
            this.$message({ type: "warning", message: err.message });
        });
    },
    /*
     * 初始化流程图
     */
    initLct() {
      // 定义公共node样式
      Graph.registerNode("custom-rect", {
        inherit: "rect",
        width: 160,
        height: 40,
        attrs: {
          body: {
            strokeWidth: 1,
            stroke: "#b6cae4",
            fill: "#fff" // 填充颜色
          },
          label: {
            textWrap: {
              width: 160,
              height: 40
            },
            fill: "#334d6d" // 文字颜色
          }
        }
      });
      this.graph = new Graph({
        resizing: {
          enabled: true
        },
        selecting: {
          modifiers: "ctrl",
          enabled: true,
          multiple: true,
          rubberband: true,
          movable: true,
          showNodeSelectionBox: true
        },
        keyboard: true,
        history: true,
        panning: {
          enabled: true
        },
        mousewheel: {
          enabled: true
        },
        grid: true,
        snapline: true,
        container: this.$refs.lctRef
      });
      this.initBtn();
    },
    // 初始化按钮
    initBtn() {
      // 移入鼠标添加按钮
      this.graph.on("cell:mouseenter", ({ e, cell }) => {
        const _this = this;
        if (cell.isNode()) {
          const tools = [
            {
              name: "button",
              args: {
                markup: [
                  {
                    tagName: "circle",
                    attrs: {
                      r: 12,
                      fill: "#759ed6",
                      cursor: "pointer"
                    }
                  },
                  {
                    tagName: "text",
                    textContent: "+",
                    selector: "icon",
                    attrs: {
                      fill: "#fff",
                      "font-size": 18,
                      "text-anchor": "middle",
                      "pointer-events": "none",
                      y: "0.3em"
                    }
                  }
                ],
                x: "98%",
                y: "98%",
                onClick({ view }) {
                  _this.editType = "add";
                  _this.activeNode = view.cell;
                  _this.$refs.editNodeDialog?.openDialog();
                }
              }
            },
            {
              name: "button",
              args: {
                markup: [
                  {
                    tagName: "circle",
                    selector: "button",
                    attrs: {
                      r: 12,
                      stroke: "#fe854f",
                      strokeWidth: 2,
                      fill: "white",
                      cursor: "pointer"
                    }
                  },
                  {
                    tagName: "text",
                    textContent: "X",
                    selector: "icon",
                    attrs: {
                      fill: "#fe854f",
                      fontSize: 10,
                      textAnchor: "middle",
                      pointerEvents: "none",
                      y: "0.3em"
                    }
                  }
                ],
                x: "98%",
                y: "0",
                onClick({ cell }) {
                  MessageBox.confirm("确认删除吗?", "警告", {
                    confirmButtonText: "确定",
                    cancelButtonText: "取消",
                    type: "warning"
                  })
                    .then(() => {
                      this.graph.removeCell(cell);
                    })
                    .catch(() => { });
                }
              }
            }
          ];
          cell.addTools(tools);
        }
      });
      // 移出鼠标取消按钮显示
      this.graph.on("cell:mouseleave", ({ cell }) => {
        if (!cell.hasTool("node-editor")) {
          cell.removeTools();
        }
      });
      // 双击弹窗编辑
      this.graph.on("node:dblclick", ({ node, cell }) => {
        this.editType = "edit";
        this.activeNode = cell;
        this.$refs.editNodeDialog?.openDialog(node.data);
      });
    },
    // 新增节点
    addNode() {
      this.editType = "init";
      this.$refs.editNodeDialog?.openDialog();
    },
    // 更新流程图
    updateLct(data) {
      if (this.editType === "add") {
        const { x, y } = this.activeNode.position();
        const id = uuid();
        // 添加节点
        this.graph.addNode({
          shape: "custom-rect",
          x: x + 300,
          y: y + Math.random() * 30,
          id: id, // 节点的唯一标识
          label: data.jkmc, // 节点标签
          data: data
        });
        // 添加线
        this.graph.addEdge({
          source: this.activeNode.id, // 起始节点 id
          target: id, // 目标节点 id
          attrs: {
            line: {
              targetMarker: "",
              strokeWidth: 1,
              stroke: "#b6cae4" // 指定 path 元素的填充色
            }
          },
          router: {
            name: "er",
            args: { offset: "center" }
          }
        });
      } else if (this.editType === "edit") {
        this.activeNode.setAttrs({ label: { text: data.jkmc } });
        this.activeNode.setData(data, { overwrite: true });
      } else if (this.editType === "init") {
        const id = uuid();
        // 添加节点
        this.graph.addNode({
          shape: "custom-rect",
          x: 300,
          y: 200,
          id: id, // 节点的唯一标识
          label: data.jkmc, // 节点标签
          data: data
        });
      }
    },
    // 保存模型
    saveMx() {
      const params = {
        fwdy: JSON.stringify(this.graph.toJSON()),
        fwdybh: this.$route.query.cs
      };
      bpfwglService
        .updateFwdy(params)
        .then(() => {
          this.$message({ type: "success", message: "保存成功!" });
        })
        .catch(err => {
          !err.isError &&
            this.$message({ type: "warning", message: err.message });
        });
    }
  }
};
</script>
<style lang="scss" scoped>
.container {
  width: 100%;
  .lct {
    margin-top: 20px;
    width: 100%;
    height: 500px;
    background: #fff;
  }
}
</style>
